package cn.demoncat.util.io.entity;

import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;

import cn.demoncat.util.lang.ByteUtil;
import cn.demoncat.util.lang.entity.LineReadCallback;
import cn.demoncat.util.lang.entity.LineReadCallback.LineReadFinishException;

/**
 * 行输出流 - 通过callback.read自定义输出方式
 * 
 * @author 延晓磊
 *
 * @since 2019年6月14日
 */
public class LineOutputStream extends OutputStream {

	// 缓存
	protected StringBuffer buf;
	// 读取器
	protected LineReadCallback callback;

	// 换行符
	protected static final char NLINE = '\n';
	protected static final char RLINE = '\r';

	public LineOutputStream(LineReadCallback callback) {
		super();
		this.callback = callback;
	}

	/**
	 * 输出byte
	 * 
	 * @param b
	 *
	 * @author 延晓磊
	 * @throws LineReadFinishException 
	 *
	 * @since 2019年6月14日
	 *
	 */
	@Override
	public synchronized void write(int b) throws LineReadFinishException {
		// 输出字符
		write((char)b);
	}

	/**
	 * 输出bytes
	 * 
	 * @param b
	 * @param off
	 * @param len
	 *
	 * @author 延晓磊
	 * @throws LineReadFinishException 
	 *
	 * @since 2019年6月14日
	 *
	 */
	@Override
	public synchronized void write(byte[] b, int off, int len) throws LineReadFinishException {
		if ((off < 0) || (off > b.length) || (len < 0) || ((off + len) - b.length > 0)) {
			throw new IndexOutOfBoundsException();
		}
		// 转换为chars
		for (char c : ByteUtil.getChars(Arrays.copyOfRange(b, off, len))) {
			// 输出字符
			write(c);
		}
	}

	/**
	 * 输出bytes
	 * 
	 * @param b
	 * @throws IOException
	 *
	 * @author 延晓磊
	 * @throws LineReadFinishException 
	 *
	 * @since 2019年6月14日
	 *
	 */
	@Override
	public synchronized void write(byte[] b) throws LineReadFinishException {
		// 转换为chars
		for (char c : ByteUtil.getChars(b)) {
			// 输出字符
			write(c);
		}
	}
	
	/**
	 * 输出行
	 * 
	 * @param line
	 * 
	 * @author 延晓磊
	 * @throws LineReadFinishException 
	 *
	 * @since 2019年6月14日
	 */
	public synchronized void write(String line) throws LineReadFinishException {
		// 行操作
		read(line);
	}
	
	/**
	 * 容量
	 */
	public synchronized int size() {
        return buf == null ? 0 : buf.length();
    }
	
	/**
	 * 关闭
	 */
	@Override
	public void close() {
		// 内存流不需要关闭
	}

	/**
	 * 刷新
	 */
	@Override
	public void flush() {
		// 内存流不需要刷新
	}
	
	/**
	 * 输出字符
	 * @throws LineReadFinishException 
	 */
	protected void write(char c) throws LineReadFinishException {
		// 忽略\r
		if (c != RLINE) {
			// 新建buf
			if (buf == null) {
				buf = new StringBuffer();
			}
			// 换行
			if (c == NLINE) {
				// 行操作
				read(buf.toString());
				buf = null;
			}else {
				// 拼接行
				buf.append(c);
			}
		}
	}
	
	/**
	 * 行读取操作
	 * 
	 * @throws LineReadFinishException 
	 */
	protected void read(String line) throws LineReadFinishException {
		callback.read(line);
	}

}
